package cn.yy.shiro;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;

@Configuration
public class ShiroConfig {

	@Bean
	public MyShiroRealm myShiroRealm(){
		MyShiroRealm myShiroRealm=new MyShiroRealm();
		myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
		return myShiroRealm;
	}
	
	@Bean  
    public SecurityManager securityManager(){  
       DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();  
       //设置realm.  
       securityManager.setRealm(myShiroRealm());  
       return securityManager;  
    }  
	
	/**  
     *  开启shiro aop注解支持.  
     *  使用代理方式;所以需要开启代码支持;  
     * @param securityManager  
     * @return  
     */  
    @Bean  
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){  
       AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();  
       authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);  
       return authorizationAttributeSourceAdvisor;  
    }  
	
	@Bean
	public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {  
        System.out.println("ShiroConfiguration.shiroFilter()");  
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();  
  
        // 必须设置SecuritManager  
        shiroFilterFactoryBean.setSecurityManager(securityManager);  
  
        // 拦截器  
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();  
  
        // 配置退出过滤器,其中的具体代码Shiro已经替我们实现了  
        filterChainDefinitionMap.put("/logout", "logout");  
  
        // <!-- 过滤链定义，从上向下顺序执行，一般将 /**放在最为下边 -->:这是一个坑呢，一不小心代码就不好使了;  
        // <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->  
  
        filterChainDefinitionMap.put("/**", "authc");  
  
        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面  
        shiroFilterFactoryBean.setLoginUrl("/login");  
        // 登录成功后要跳转的链接  
        shiroFilterFactoryBean.setSuccessUrl("/index");  
        // 未授权界面;  
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");  
  
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);  
        return shiroFilterFactoryBean;  
  
    }  
  
	/**  
     * 凭证匹配器  
     * （由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了  
     *  所以我们需要修改下doGetAuthenticationInfo中的代码;  
     * ）  
     * @return  
     */  
    @Bean  
    public HashedCredentialsMatcher hashedCredentialsMatcher(){  
       HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();  
        
       hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;  
       hashedCredentialsMatcher.setHashIterations(2);//散列的次数，比如散列两次，相当于 md5(md5(""));  
        
       return hashedCredentialsMatcher;  
    }  
}
